const stadiumService = require('../service/stadium.service')
const userService = require('../service/user.service')
const orderService = require('../service/order.service')
const {
    STADIUM_ID_REQUIRED,
    STADIUM_NOT_EXISTED,
    STADIUM_IS_CLOSING,
    ORDER_BALANCE_INSUFFICIENT,
    ORDER_ID_REQUIRED,
    ORDER_NOT_EXISTED,
    ORDER_NOT_PAYED,
} = require('../error/errorType')

function getCurTime() {
    let res = new Date()
    let h = res.getHours()
    let m = res.getMinutes()
    let s = res.getSeconds()
    h = h >= 10 ? h : `0${h}`
    m = m >= 10 ? m : `0${m}`
    s = s >= 10 ? s : `0${s}`
    return `${h}:${m}:${s}`
}

function ttos(time) {
    let arr = time.split(':')
    let [ HH, mm, ss ] = arr
    HH = parseInt(HH) * 3600
    mm = parseInt(mm) * 60
    ss = parseInt(ss)
    return HH + mm + ss
}

// 计算花费的金额
function getCost(createTime, curTime, stadium) {
    let d1 = new Date(createTime)
    let d2 = new Date(curTime)
    let _d1 = new Date(d1.toLocaleString().split(' ')[0])
    let _d2 = new Date(d2.toLocaleString().split(' ')[0])

    let dayDiff = (_d2.getTime() - _d1.getTime()) / 1000 / 3600 / 24

    const { startTime, endTime, price_per_hour: price } = stadium
    let secondDiff, cost
    // 计算秒差
    if (dayDiff != 0) {
        let st = ttos(startTime), et = ttos(endTime)
        let first = et - ttos(d1.toLocaleString().split(' ')[1])
        let middle = (dayDiff - 1) * (et - st)
        let last = ttos(d2.toLocaleString().split(' ')[1]) - st
        secondDiff = first + middle + last
    } else {
        secondDiff = (d2.getTime() - d1.getTime()) / 1000
    }
    cost = Number((secondDiff * price / 3600).toFixed(2))
    return cost
}


const verifyStadium = async (ctx, next) => {
    const { stadiumId } = ctx.request.body
    // 判断有无传场馆id
    if (!stadiumId) {
        return ctx.app.emit('error', new Error(STADIUM_ID_REQUIRED), ctx)
    }
    // 判断存不存在该场馆
    let [ stadiumInfo ] = await stadiumService.getById(stadiumId)
    if (stadiumInfo) {
        const { startTime, endTime } = stadiumInfo
        const curTime = getCurTime()
        // 判断是否在营业时间内
        if (curTime >= startTime && curTime <= endTime) {
            ctx.stadiumInfo = stadiumInfo
            ctx.curTime = curTime
        } else {
            return ctx.app.emit('error', new Error(STADIUM_IS_CLOSING), ctx)
        }
    } else {
        return ctx.app.emit('error', new Error(STADIUM_NOT_EXISTED), ctx)
    }

    await next()
}

// 能进入这个中间件的前提: 场馆在营业时间内
const verifyOrder = async (ctx, next) => {
    // 根据stadiumId和userId获取订单
    const { id: stadiumId } = ctx.stadiumInfo
    const { id: userId } = ctx.userInfo

    let [ result ] = await orderService.getOne(stadiumId, userId)
    let mode = 'end' // 默认为结束订单
    if (result) { // 订单存在
        // 根据订单status判断是否对用户进行扣费
        if (result.status == 1) { // 不扣费, 这里相当于用户再次预约了相同的场馆
            mode = 'update'
            ctx.orderId = result.id
        } else { // 扣费
            // 计算扣费金额
            let { createAt } = result
            let costAmount = getCost(createAt, Date.now(), ctx.stadiumInfo)

            // 判断结算余额是否大于用户所剩余额
            const { name } = ctx.userInfo
            let [ user ] = await userService.getUserInfoByName(name)
            if (user.amount < costAmount) {
                return ctx.app.emit('error', new Error(ORDER_BALANCE_INSUFFICIENT), ctx)
            }

            ctx.orderId = result.id
            ctx.cost = costAmount
            ctx.rest = Number(user.amount)
        }
    } else { // 订单不存在 => 创建订单
        mode = 'start'
    }
    ctx.mode = mode
    await next()
}

const verifyPager = async (ctx, next) => {
    // 处理分页相关的参数
    let { currentPage, pageSize } = ctx.query
    currentPage -= 0
    pageSize -= 0

    if (!currentPage) currentPage = 1
    if (!pageSize) pageSize = 5

    if (currentPage <= 0) currentPage = 1
    if (pageSize <= 0) pageSize = 5

    let pageNum = Math.max((currentPage - 1) * pageSize, 0)

    ctx.pager = { pageNum, currentPage, pageSize }
    await next()
}

const verifyRemove = async (ctx, next) => {
    let { id: orderId } = ctx.request.params
    if (!orderId) {
        return ctx.app.emit('error', new Error(ORDER_ID_REQUIRED), ctx)
    }
    let [ order ] = await orderService.getOneById(orderId)
    if (!order) {
        return ctx.app.emit('error', new Error(ORDER_NOT_EXISTED), ctx)
    }
    // 根据status字段判断该订单是否已结算
    if (order.status == 0) {
        return ctx.app.emit('error', new Error(ORDER_NOT_PAYED), ctx)
    }
    ctx.orderId = orderId
    await next()
}

module.exports = {
    verifyOrder,
    verifyStadium,
    verifyPager,
    verifyRemove,
}